﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MonoTouchAutoBind
{
    class MonotouchPage
    {

        private MonotouchBind currentBind;
        private List<MonotouchBind> bindEngine = new List<MonotouchBind>() { 
            new BindProtocol(),
            new BindInterface(),
            new BindEnum(),
            new BindTypedefBlock(),
        };

        private List<MonotouchBind> bindResult;
        public string ObjctiveCText { get; set; }
        public MonotouchPage()
            : this("")
        {
            Parse();
        }

        public MonotouchPage(string objctiveCText)
        {
            this.ObjctiveCText = objctiveCText;
            Parse();
        }


        public string GeneratedCode()
        {

            StringBuilder sb = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
            foreach (var bind in bindResult)
            {
                sb.AppendLine(bind.GenerateCSharp());

                bind.DelegateCodeList.ForEach((m) =>
                {
                    sb2.AppendLine(m);
                });
            }

            return sb2.ToString() + Environment.NewLine + sb.ToString();
        }


        private void Parse()
        {
            bindResult = new List<MonotouchBind>();
            string code = "";
            using (System.IO.StringReader sr = new System.IO.StringReader(this.ObjctiveCText))
            {
                while (sr.Peek() > 0)
                {
                    code = sr.ReadLine();
                    if (code.IndexOf("//") >= 0)
                    {
                        code = code.Substring(0, code.IndexOf("//"));
                    }

                    if (code.Trim().Length == 0)
                    {
                        continue;
                    }
                    if (code.TrimStart().StartsWith(@"//"))
                    {
                        DebugOut.Instance.Print(code); 
                        continue;
                    }
                    if (code.TrimStart().StartsWith(@"#import"))
                    {
                        DebugOut.Instance.Print(code);
                        continue;
                    }


                    if (currentBind == null)
                    {
                        currentBind = bindEngine.Find(m => { return m.CanParse(code); });

                        if (currentBind != null)
                        {
                            Type bindType = currentBind.GetType();
                            MonotouchBind tmpBind = (MonotouchBind)Activator.CreateInstance(bindType);
                            currentBind = tmpBind;
                            bindResult.Add(tmpBind);
                        }
                    }

                    if (currentBind != null)
                    {
                        currentBind.PushCode(code);
                        if (currentBind.ParseFiniseStatus == ParseStatus.Finished)
                        {
                            currentBind = null;
                        }
                        continue;
                    }
                    else
                    {
                        DebugOut.Instance.Print(code);
                    }

                }



            }


        }


    }
}
